package com.example.dakotanews.controller;

import com.example.dakotanews.dto.NewsEditFormDTO;
import com.example.dakotanews.dto.utils.ApiResponse;
import com.example.dakotanews.dto.utils.ResponseCode;
import com.example.dakotanews.service.NewsService;
import com.example.dakotanews.utils.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/news")
public class NewsController {

    private final NewsService newsService;
    private final JwtUtil jwtUtil;

    // 使用构造函数进行自动装配
    @Autowired
    public NewsController(
            NewsService newsService,
            JwtUtil jwtUtil
    ) {
        this.newsService = newsService;
        this.jwtUtil = jwtUtil;
    }

    /**
     * @name 获取新闻详情接口
     * @description 根据新闻的ID，获取对应新闻的详细信息
     * @param newsId （必需）新闻Id
     * @param jwt （可选）请求头中的授权信息
     * @return 返回新闻详情等信息封装成的JSON
     */
    @GetMapping("/getDetail")
    public ApiResponse<Object> getNewsDetail(
            @RequestParam Integer newsId,
            @RequestHeader(value = "Authorization", required = false)String jwt) {

        // 解析授权信息中的用户ID
        Integer userId = jwtUtil.extractUserIdFromJWT(jwt);

        return newsService.getNewsAllInfo(newsId, userId);
    }

    /**
     * @description 新闻操作接口
     * @param opType （必需）操作类型，1为点赞，2为点踩，3为收藏
     * @param jwt （可选）用户验证信息，此处实际上是必选，但是逻辑是若用户发送未登录的请求则在控制层直接返回401
     * @return 返回处理结果
     */
    @GetMapping("/operateNews")
    public ApiResponse<Object> operateNews(
            @RequestParam Integer newsId,
            @RequestParam Integer opType,
            @RequestHeader(value = "Authorization", required = false)String jwt) {

        Integer userId = jwtUtil.extractUserIdFromJWT(jwt);
        if (userId == null) {
            return new ApiResponse<>(ResponseCode.UNAUTHORIZED, "未授权的请求", "请先登录");
        }

        // 判断互动操作是哪一种
        if (opType == 1){
            return newsService.supportNews(newsId, userId);
        }else if (opType == 2) {
            return newsService.oppositeNews(newsId, userId);
        }else if (opType == 3) {
            return newsService.collectNews(newsId, userId);
        }else {
            return new ApiResponse<>(ResponseCode.BAD_REQUEST, "未知参数", "无法识别操作类型");
        }
    }

    /**
     * 公有接口
     * @description 获取新闻分类接口
     * @return 返回新闻分类列表
     */
    @GetMapping("/getSorts")
    public ApiResponse<Object> getNewsSorts(){
        return newsService.getNewsSort();
    }

    /**
     * @description 获取新闻推荐接口
     * @param newsSort 新闻分类，0为不分类
     * @return 新闻推荐列表
     */
    @GetMapping("/getRecommends")
    public ApiResponse<Object> getNewsRecommends(
            @RequestParam Integer newsSort,
            @RequestParam(defaultValue = "1")int page,
            @RequestParam(defaultValue = "0")int pageSize,
            @RequestHeader(value = "Authorization", required = false)String jwt) {

        Integer userId = jwtUtil.extractUserIdFromJWT(jwt);
        if(userId != null) {
            // TODO 若已登录，进行个性化推荐
            // return newsService.personalizedRecommend(newsSort, userId, page, pageSize);
            return newsService.commonRecommend(newsSort, page, pageSize);
        }else {
            // 若未登录，进行一般推荐
            return newsService.commonRecommend(newsSort, page, pageSize);
        }
    }

    /**
     * @description 获取新闻编辑表单数据接口。完全私有接口
     * @param newsId 待编辑的新闻ID
     * @return 返回新闻编辑表单DTO
     */
    @GetMapping("/getNewsEditForm")
    public ApiResponse<Object> getNewsEditForm(
            @RequestParam Integer newsId,
            @RequestHeader(value = "Authorization", required = false)String jwt) {

        Integer userId = jwtUtil.extractUserIdFromJWT(jwt);
        if (userId == null) {
            return new ApiResponse<>(ResponseCode.UNAUTHORIZED, "未授权的请求", "请先登录");
        }

        return newsService.getNewsEditForm(newsId, userId);
    }

    /**
     * @description 保存并发布新闻功能接口
     * @param newsEditFormDTO （必选，部分成员可选）请求体参数，待提交的新闻表单信息
     * @param newsId （可选）若修改时调用接口则需要在请求参数中额外传递新闻ID作参数
     * @param jwt （必选）完全私有接口，需要检验ID是否
     * @return 返回操作记录的ID（若为新增则返回新的 记录的ID，修改则返回修改的记录的ID）
     */
    @PostMapping("/publishNews")
    public ApiResponse<Object> saveOrUpdateNews(
            @RequestBody NewsEditFormDTO newsEditFormDTO,
            @RequestParam(required = false)Integer newsId,
            @RequestHeader(value = "Authorization", required = false)String jwt) {

        Integer userId = jwtUtil.extractUserIdFromJWT(jwt);
        if (userId == null) {
            return new ApiResponse<>(ResponseCode.UNAUTHORIZED, "未授权的请求", "请先登录");
        }

        if (newsId == null) {
            // 若newsId为空，说明是新增新闻记录，调用添加记录的方法，传递用户ID查询作者信息
            return newsService.addNews(newsEditFormDTO, userId);
        }else {
            // 若不为空说明是修改记录，调用修改记录的方法，传递新闻ID标明应该修改哪篇新闻
            return newsService.editNews(newsEditFormDTO, newsId);
        }
    }
}
